/**
 * @description 实体-控制器
 * @since 2019-11-12
 * @author Rid King
*/

const ox = require('@daelui/oxjs')
const Service = require('./service.js')

class Controller extends ox.Controller {
  /**
   * @function 构造方法
  */
  constructor (args) {
    super(args)
    // 服务
    this.$service = new Service(args)
  }

  /**
   * @function 增删改事件触发
  */
  emit (name, action, res) {
    super.emit(name, action, res)
  }

  // 数据服务
  saas (action, extender) {
    // 解析数据
    return this.solveAction(action, extender).then(async action => {
      return new Promise(async (resolve, reject) => {
        let reg = /\/dapi\/saas((\/[^\/\?]+)+)/ig
        let path = action.req.path
        let matched = (reg.exec(path) || [])[1] || ''
        let args = matched.split('/').filter(item => !!item)
        // 查询实体
        let entRes = await this.$router.getControllInstance({path: '/tigerlair/entity'}).query({}, {
          action: {},
          query: {},
          params: {
            code: args[0],
            status: '1'
          }
        })
        // 未找到实体
        if (!entRes.data) {
          resolve({data: null, success: 0, status: 404, msg: 'Entity not found'})
          return true
        }

        // 查询接口
        let apiRes = await this.$router.getControllInstance({path: '/tigerlair/dapi'}).query({}, {
          action: {},
          query: {},
          params: {
            eid: entRes.data.id,
            name: args[1] || -999,
            method: action.req.method.toLowerCase(),
            status: '1'
          }
        })

        // 未找到接口
        if (!apiRes.data) {
          resolve({data: null, success: 0, status: 404, msg: 'Api not found'})
          return true
        }

        // 查询应用
        let mappRes = await this.$router.getControllInstance({path: '/tigerlair/mapp'}).query({}, {
          action: {},
          query: {},
          params: {
            id: entRes.data.mid,
            status: '1'
          }
        })
        // 未找到应用
        if (!mappRes.data) {
          resolve({data: null, success: 0, status: 404, msg: 'Mapp not found'})
          return true
        }

        // 应用路径
        let db = this.route.scope.CONFIG.db
        let constant = this.route.scope.CONFIG.constant
        let mappPath = constant.deployPath + '/' + mappRes.data.code
        let dbPath = mappPath + '/server/db'
        // 控制器实例
        let controller = this.getController({
          table: entRes.data.code,
          config: {
            db: {
              type: db.type, // 数据库类型
              define: dbPath, // 表定义路径
              hostname: mappPath + '/xdata', // 服务器地址
              database: 'db', // 数据库名称
              username: '', // 用户名
              password: '', // 密码
              hostport: '', // 端口
              dsn: '', //
              params: '', // 数据库连接参数
              charset: '', // 数据库编码默认采用utf8
              prefix: '', // 数据库表前缀
              debug: false, // 数据库调试模式
              deploy: 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
              rw_separate: false, // 数据库读写是否分离 主从式有效
              master_num: 1, // 读写分离后 主服务器数量
              slave_no: 1, // 指定从服务器序号
              db_like_fields: ''
            }
          }
        })

        // 未找到方法
        let actor = apiRes.data.code
        if (!controller[actor]) {
          resolve({data: null, success: 0, status: 404, msg: 'Action not found'})
          return true
        }

        // 调用接口
        controller[actor]({}, {
          action: action
        }).then((res) => {
          resolve(res)
        }).catch(e => {
          resolve({data: null, success: 0, status: 404, msg: 'Action run error'})
        })
      })
    })
  }

  getController ({ table, config }) {
    // 控制器
    class Controller extends ox.Controller {
      /**
       * @function 构造方法
      */
      constructor (args) {
        super(args)
        // 服务
        this.$service = new Service(args)
      }
    }
    // 服务
    class Service extends ox.Service {
      /**
       * @function 构造方法
      */
      constructor (args) {
        super(args)
        // 模型
        this.$model = new Model(args)
      }
    }
    // 模型
    class Model extends ox.Model {
      /**
       * @function 构造方法
      */
      constructor (args) {
        super(args)
        // 表配置
        let db = this.route.scope.CONFIG.db
        // 表名
        this.table = table
        // 指定DB类
        let DBClass = ox.dbFactory.getDBClass(db.type)
        // 数据库
        this.$db = new DBClass(Object.assign({table: this.table}, db))
      }
    }

    let route = this.route
    // 路由配置
    const sassRoute = {
      app: route.app,
      routes: route.routes,
      scope: { CONFIG: config },
      moudle: route.moudle,
      packager: route.packager,
      application: route.application,
      CONFIG: config
    }
    return new Controller({ route: sassRoute })
  }
}

module.exports = Controller